package com.apache.passport.service.plugins;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SystemTools;
import com.apache.database.db.IDao;
import com.apache.database.model.MethodParam;
import com.apache.passport.common.DesUtils;
import com.apache.passport.common.LoginCacheErrTimer;
import com.apache.passport.entity.BlackRoster;
import com.apache.passport.entity.LoginInfo;
import com.apache.passport.entity.LonErrToken;
import com.apache.passport.entity.Token;
import com.apache.passport.entity.UctUser;
import com.apache.passport.manager.BlackRosterManager;
import com.apache.passport.manager.LoginInfoManager;

/**
 * description:  用户登录插件
 * @author Hou Dayu 创建时间：2014-12-19  
 * @Copyright(c)2014:
 */
public class LoginUserPlugin implements PluginConnector {

	protected IDao uctUserDao;

	protected IDao blackRosterDao;
	private LoginInfoManager loginInfoManager;
	private BlackRosterManager blackRosterManager;

	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

	public void setUctUserDao(IDao uctUserDao) {
		this.uctUserDao = uctUserDao;
	}

	/**
	 * TODO 用户密码校验  
	 * @see com.apache.api.manager.PluginConnector#execute(com.apache.api.vo.ParamsVo)
	 */
	@Override
	public Object execute(ParamsVo vo) throws Exception {
		boolean flag = false;
		String tokenId = (String) vo.getParams("tokenId");
		String sessionId = (String) vo.getParams("sessionId");
		String remoteIp = (String) vo.getParams("remoteIp");
		String synFlag = SystemTools.getInstance().getValue("synFlag");
		ParamsVo<UctUser> vos = new ParamsVo<UctUser>();
		vos = vo;
		//登录前首先从数据库中查询下该用户是否存在于黑名单中
		BlackRoster br = (BlackRoster) getBrInfoByIp(vo);
		if (!Validator.isEmpty(br)) {
			LonErrToken token = new LonErrToken();
			token.setLoginCount("12");
			token.setLoginTime(br.getBrCreatetime());
			//2015年1月29日13:02:54  将用户名添加到错误token中
			token.setUserEname(vos.getObj().getUserEname());
			token.setCacheId(remoteIp + br.getBrAccount());
			//存储缓存
			SystemTools.getInstance().getCache("loginErrToken").createCacheObject(remoteIp + br.getBrAccount(), token);
			return false;
		}

		//查询用户是否存在
		UctUser obj = (UctUser) getInfoByEname(vo);

		//判断用户是否存在
		if (!Validator.isEmpty(obj)) {
			String userEname = obj.getUserEname();
			String upass = (String) vo.getParams("userPass");
			//判断密码是否正确
			if ((obj.getUserPass()).equalsIgnoreCase(upass)) {
				//虽然密码正确,但是需要判断下之前缓存中是否存在该用户的登陆错误信息,如果存在,则依然返回等待
				LonErrToken tokenE = (LonErrToken) SystemTools.getInstance().getCache("loginErrToken")
						.getCacheCloneByKey(remoteIp + obj.getUserEname());
				if (!Validator.isEmpty(tokenE)) {
					String count = tokenE.getLoginCount();
					int c = Integer.parseInt(count);
					if ("3".equals(tokenE.getLoginCount()) || "6".equals(tokenE.getLoginCount())
							|| "9".equals(tokenE.getLoginCount()) || c > 12) {
						//如果错误次数等于以上几个参数,也同样需要校验下时间是否已经过期,防止时间已过,且登录密码正确,却一直没有更新缓存
						//setErrToken(vo, remoteIp, br, obj);
						LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
						return false;
					}
				}

				//将所有项存储到对象中
				Token token = new Token();

				vo.setParams("tokenId", tokenId);

				token.setTokenId(tokenId);
				token.setSessionId(sessionId);
				flag = true;
				//校验密码成功后,则表示用户存在且已经登录成功,则将用户数据写入到缓存中
				String desEname = DesUtils.getInstance().encrypt(obj.getUserEname());
				token.setUserEname(desEname);
				if (!Validator.isNull(obj.getMobile())) {
					String desMobile = DesUtils.getInstance().encrypt(obj.getMobile());
					token.setMobile(desMobile);
				}
				if (!Validator.isNull(obj.getEmail())) {
					String desEmail = DesUtils.getInstance().encrypt(obj.getEmail());
					token.setEmail(desEmail);
				}

				//添加cname
				if (!Validator.isNull(obj.getUserCname())) {
					String desCname = obj.getUserCname();
					token.setUserCname(desCname);
				}
				//获取数据库中上次登录的信息
				ParamsVo<LoginInfo> param = new ParamsVo<LoginInfo>();
				param.setInfoId(obj.getUserEname());
				LoginInfo loginInfo = (LoginInfo) loginInfoManager.getInfoById(param);
				token.setLoginInfo(loginInfo);
				//如果登录成功后,清空错误记录缓存
				SystemTools.getInstance().getCache("loginErrToken").removeCacheObject(remoteIp + obj.getUserEname());

				//如果属于单态,使用单态只应用在登录场景,如果在飞单态情况下登录成功,
				//其修改了配置文件,使用单态,则无法启到单态登录的效果,因为此功能只添加至登录操作中
				if ("1".equals(synFlag)) {
					String tokenMapId = (String) SystemTools.getInstance().getCache("userEnaemForTokenId")
							.getCacheCloneByKey(desEname);
					if (!Validator.isNull(tokenMapId)) {
						SystemTools.getInstance().getCache("loginToken").removeCacheObject(tokenMapId);
					}
					SystemTools.getInstance().getCache("userEnaemForTokenId").createCacheObject(desEname, tokenId);
					//存储缓存
					SystemTools.getInstance().getCache("loginToken").createCacheObject(tokenId, token);
				} else {
					//存储缓存
					SystemTools.getInstance().getCache("loginToken").createCacheObject(tokenId, token);
				}

			} else {
				//setErrToken(vo, remoteIp, br, obj);
				LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
			}
		} else {
			//setErrToken(vo, remoteIp, br, obj);
			LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
		}
		return flag;
	}

	/**
	 * description:  根据ename,手机号,邮箱查询用户信息
	 * @param vo
	 * @return  
	 * @author Hou Dayu 
	 * @update 2014-12-19
	 */
	public Object getInfoByEname(ParamsVo<UctUser> vo) {
		String userEname = vo.getObj().getUserEname();
		if (Validator.isNull(userEname)) {
			return null;
		}
		String sql = uctUserDao.getSql(3);// from UctUser where userEname :=userEname

		String mobileLogin = SystemTools.getInstance().getValue("mobileLogin");
		String emailLogin = SystemTools.getInstance().getValue("emailLogin");

		if ("1".equals(mobileLogin)) {
			sql += "or mobile :=userEname ";
		}
		if ("1".equals(emailLogin)) {
			sql += "or email :=userEname ";
		}

		MethodParam param = new MethodParam("ByUserEname", "", sql, "com.apache.passport.entity.UctUser");
		param.setParams("userEname", userEname);
		if ("1".equals(mobileLogin)) {
			param.setParams("mobile", userEname);
		}
		if ("1".equals(emailLogin)) {
			param.setParams("email", userEname);
		}
		return uctUserDao.selectSingle(param);
	}

	/**
	 * description:  根据IP及用户名获取黑名单
	 * @param vo
	 * @return  
	 * @author Hou Dayu 
	 * @update 2014-12-24
	 */
	public Object getBrInfoByIp(ParamsVo<UctUser> vo) {
		String remoteIp = (String) vo.getParams("remoteIp");
		String userEname = (String) vo.getParams().get("userEname");
		//只验证用户名
		String sql = blackRosterDao.getSql(4);
		if (!Validator.isNull(remoteIp)) {
			sql += " and brIpaddress :=brIpaddress ";
		}
		MethodParam param = new MethodParam("ByIpOrUserEname", "", sql, BlackRoster.class.getName());
		param.setParams("brIpaddress", remoteIp);
		param.setParams("brAccount", userEname);
		return blackRosterDao.selectSingle(param);
	}

	public void setLoginInfoManager(LoginInfoManager loginInfoManager) {
		this.loginInfoManager = loginInfoManager;
	}

	public void setBlackRosterDao(IDao blackRosterDao) {
		this.blackRosterDao = blackRosterDao;
	}

	public void setBlackRosterManager(BlackRosterManager blackRosterManager) {
		this.blackRosterManager = blackRosterManager;
	}

}
